Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: make the tests pass #41

Merged
merged 11 commits into from
Jul 5, 2024
Merged

fix: make the tests pass #41

merged 11 commits into from
Jul 5, 2024

Conversation

diegomrsantos
Copy link
Collaborator

@diegomrsantos diegomrsantos commented Jun 26, 2024

  • upgrade dependencies
  • fix compilation issues
  • fix deadlock in test

@diegomrsantos diegomrsantos changed the title chore: upgrade nimcrypto chore: upgrade dependencies Jun 26, 2024
@diegomrsantos diegomrsantos changed the title chore: upgrade dependencies fix: make the test pass Jun 28, 2024
@diegomrsantos diegomrsantos changed the title fix: make the test pass fix: make the tests pass Jun 28, 2024
Comment on lines +52 to +53
# let stream = state.stream.valueOr:
# raise newException(QuicError, "stream is closed")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get why you removed those two lines. If stream is none, it'll raise an error nevertheless. It'll just be less precise.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this code, there's a compilation error: Error: (ref QuicError)(msg: "stream is closed", parent: nil) can raise an unlisted exception: ref QuicError. Would you happen to know how to fix it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

method write(state: OpenStream, bytes: seq[byte]) {.async.} =
  let stream = state.stream.valueOr:
    raise newException(QuicError, "stream is closed")
  return state.connection.send(state.stream.get.id, bytes)

fails with:
Error: undeclared identifier: 'setResult'

Copy link

@lchenut lchenut Jul 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dug a bit into this. Here a solution:

method write(state: OpenStream, bytes: seq[byte]): Future[void] {.raises: [QuicError].} =    
  let stream = state.stream.valueOr:    
    raise newException(QuicError, "stream is closed")    
  state.connection.send(state.stream.get.id, bytes)    

With the base method modified aswell:

method write*(state: StreamState, bytes: seq[byte]) {.base, async, raises: [QuicError].} =    
  doAssert false # override this method                                     

But I'm not satisfied at all about this. It uses an old version of chronos and thus is not up to date regarding exception. With the newer version (> 4.0 I think), you'll use {.async: (raises: [QuicError]).}.
It uses aswell upraises which I just discover, it seems to be an exception tracking for older versions of nim... Which I'm hesitant to use aswell.

But it's clearly not the goal of this PR. So I might just approve if you have nothing else to add even though it should be changed/updated in the future.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the base method would require changing all the other implementations, I guess. I'm not sure yet if we should raise this error. As you said, not the point of this PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a link to this PR

@@ -44,7 +44,8 @@ proc startSending(connection: Connection, remote: TransportAddress) =
try:
let datagram = await connection.quic.outgoing.get()
await connection.udp.sendTo(remote, datagram.data)
except TransportError:
except TransportError as e:
connection.loop.fail(e) # This might need to be revisited
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really necessary for the tests to work? It looks odd to me.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this, the test hangs forever cause of a deadlock in chronos. I'll explain it better.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a brief explanation is a good idea.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a link to this PR

@diegomrsantos
Copy link
Collaborator Author

diegomrsantos commented Jul 2, 2024

ca9a029 is a fix - possibly not the best one - for a deadlock related to chronos.

import chronos

type
  Connection = ref object
    loop: Future[void]

proc drop(connection: Connection) {.async.} =
  await sleepAsync(1.milliseconds)
  await cancelAndWait(connection.loop)

proc testFoo(connection: Connection) {.async.} =
  proc send() {.async.} =
    await connection.drop()
  connection.loop = send()

when isMainModule:
  var connection = Connection()
  waitFor testFoo(connection)
  waitFor connection.loop

The code above never finishes and I believe something similar is happening here.
cc @kaiserd @markspanbroek @arnetheduck

@@ -44,7 +44,8 @@ proc startSending(connection: Connection, remote: TransportAddress) =
try:
let datagram = await connection.quic.outgoing.get()
await connection.udp.sendTo(remote, datagram.data)
except TransportError:
except TransportError as e:
connection.loop.fail(e) # This might need to be revisited

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a brief explanation is a good idea.

@lchenut
Copy link

lchenut commented Jul 3, 2024

Replacing cancelAndAwait by cancelSoon work in this case. I'm not sure if it's something you can do in this specific PR.

@diegomrsantos
Copy link
Collaborator Author

Replacing cancelAndAwait by cancelSoon work in this case. I'm not sure if it's something you can do in this specific PR.

if the future represents the send async proc, it makes sense to fail the future with the error that happened inside send.

@diegomrsantos diegomrsantos merged commit 27bd6b2 into main Jul 5, 2024
3 checks passed
@diegomrsantos diegomrsantos deleted the update-nimcrypto branch July 5, 2024 12:24
diegomrsantos added a commit that referenced this pull request Aug 14, 2024
This PR adds the logs used to find the cause of the deadlock fixed in
ca9a029.

Related to #41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants